home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / ODF / Found / FWString / SLTxtPar.cpp < prev    next >
Encoding:
Text File  |  1996-09-17  |  12.4 KB  |  381 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                SLTxtPar.cpp
  4. //    Release Version:    $ ODF 2  $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWFound.hpp"
  11.  
  12. #ifndef SLTXTPAR_H
  13. #include "SLTxtPar.h"
  14. #endif
  15.  
  16. #ifndef SLPRIDEB_H
  17. #include "SLPriDeb.h"
  18. #endif
  19.  
  20. #ifndef SLPRIMEM_H
  21. #include "SLPriMem.h"
  22. #endif
  23.  
  24. #ifdef FW_BUILD_MAC
  25. #include <Script.h>
  26. #endif
  27.  
  28. #ifdef FW_BUILD_MAC
  29. #pragma segment Strings
  30. #endif
  31.  
  32. //========================================================================================
  33. //    struct FW_ODTradITextData
  34. //========================================================================================
  35.  
  36. struct FW_ODTradITextData
  37. {
  38.     FW_Locale    fLocale;
  39.     char        fText[1];        // Variable length array!
  40. };
  41.  
  42. //========================================================================================
  43. //    Parameter functions for Traditional Mac Text
  44. //========================================================================================
  45.  
  46. const size_t kTradMacTextOffset = sizeof(FW_Locale);
  47.  
  48. // We declare the following functions extern "C" even though they are static
  49. // (and therefore private to this module) because the FW_ODITextFunctions struct
  50. // expects an array of "C" functions.  A strict type checking compiler such as
  51. // SCpp will not allow you to do it otherwise. - (SFU)
  52.  
  53. extern "C"
  54. {
  55.     static void TradMac_GetODITextParams(ODIText* text, 
  56.                                         FW_ODITextParams* params,
  57.                                         FW_PlatformError* error);
  58.     static FW_Boolean TradMac_IsCharacterStart(ODIText* text, 
  59.                                         FW_BytePosition, 
  60.                                         FW_BytePosition,
  61.                                         FW_PlatformError* error);
  62.     static FW_BytePosition TradMac_GetBytePosition(ODIText* text, 
  63.                                         FW_CharacterPosition,
  64.                                         FW_PlatformError* error);
  65.     static void TradMac_SetCapacity(ODIText *text,
  66.                                     long capacity,
  67.                                     FW_Boolean deletePrevBuffer,
  68.                                     FW_PlatformError* error);
  69.     static void TradMac_SetLength(ODIText* text, 
  70.                                         long,
  71.                                         FW_PlatformError* error);
  72.     static void TradMac_SetLocale(ODIText* text, 
  73.                                         FW_Locale locale,
  74.                                         FW_PlatformError* error);
  75. }
  76.  
  77. //----------------------------------------------------------------------------------------
  78. // TradMac_GetODITextParams
  79. //----------------------------------------------------------------------------------------
  80.  
  81. static void TradMac_GetODITextParams(ODIText *text, 
  82.                                     FW_ODITextParams* params,
  83.                                     FW_PlatformError* error)
  84. {
  85.     *error = 0;
  86.     params->fTextStart = (char*) text->text._buffer + kTradMacTextOffset;
  87.     params->fTextByteLength = text->text._length - kTradMacTextOffset;
  88.     params->fTextByteCapacity = text->text._maximum - kTradMacTextOffset;
  89. #ifdef FW_BUILD_MAC
  90.     ODByteArray *array = &text->text;
  91.     FW_ODTradITextData *iTextData = (FW_ODTradITextData *) array->_buffer;
  92.     params->fTextLocale = iTextData->fLocale;
  93. #else
  94.     // This is a hack until OpenDoc for Windows does the right thing
  95.     params->fTextLocale.fScriptCode = 0;
  96.     params->fTextLocale.fLangCode = 0;
  97. #endif
  98. }
  99.  
  100. //----------------------------------------------------------------------------------------
  101. // TradMac_IsCharacterStart
  102. //----------------------------------------------------------------------------------------
  103.  
  104. static FW_Boolean TradMac_IsCharacterStart(ODIText *text,                                             
  105.                                     FW_BytePosition knownCharacterStartPosition, 
  106.                                     FW_BytePosition positionToCheck,
  107.                                         FW_PlatformError* error)
  108. {
  109.     FW_Boolean result = true;    // assume true, which will be the case for single-byte scripts
  110.     *error = 0;
  111.  
  112. #ifdef FW_BUILD_MAC
  113.     //KVV For Windows, always assume single-byte character set
  114.     ODByteArray *array = &text->text;
  115.     FW_ODTradITextData *data = (FW_ODTradITextData *) array->_buffer;
  116.     
  117.     if (!::FW_LocaleIsSingleByte(data->fLocale))
  118.     {
  119.         // return true if byte is first byte of a character
  120.         // This doesn't make a distinction between single-byte and double-byte characters
  121.         result = ::CharacterByteType(data->fText+knownCharacterStartPosition, 
  122.                         positionToCheck-knownCharacterStartPosition, 
  123.                         data->fLocale.fScriptCode) != smLastByte;
  124.     }
  125. #endif
  126.  
  127.     return result;
  128. }
  129.  
  130. //----------------------------------------------------------------------------------------
  131. // TradMac_GetBytePosition
  132. //----------------------------------------------------------------------------------------
  133.  
  134. static FW_BytePosition TradMac_GetBytePosition(ODIText *text, FW_CharacterPosition position,
  135.                                         FW_PlatformError* error)
  136. {
  137.     FW_BytePosition result = position;    // assume single byte characters
  138.     *error = 0;
  139.     
  140.     ODByteArray *array = &text->text;
  141.     FW_ODTradITextData *data = (FW_ODTradITextData *) array->_buffer;
  142.  
  143. #ifdef FW_BUILD_MAC
  144.     //KVV For Windows, always assume single-byte character set
  145.     if (!::FW_LocaleIsSingleByte(data->fLocale))
  146.     {
  147.         char* p = data->fText;
  148.         short offset = 0;
  149.         short byteType;
  150.         FW_CharacterPosition chPos = 0;
  151.         FW_BytePosition bytePos = 0;
  152.         while (chPos < position)
  153.         {
  154.             byteType = ::CharacterByteType(p, offset, data->fLocale.fScriptCode);
  155.             bytePos++;
  156.             if (byteType == smFirstByte)
  157.             {
  158.                 offset = 1;
  159.             }
  160.             else    // (byteType == smLastByte) || (byteType == smSingleByte)
  161.             {
  162.                 chPos++;
  163.                 p += offset;    // offset is 1 or 0, depending on previous byte
  164.                 p++;
  165.                 offset = 0;
  166.             }
  167.         }
  168.         result = bytePos;
  169.     }
  170. #endif
  171.  
  172.     return result;
  173. }
  174.  
  175. //----------------------------------------------------------------------------------------
  176. // TradMac_SetCapacity
  177. //----------------------------------------------------------------------------------------
  178.  
  179. static void TradMac_SetCapacity(ODIText *text,
  180.                                     long capacity,
  181.                                     FW_Boolean deletePrevBuffer,
  182.                                     FW_PlatformError* error)
  183. {
  184.     FW_ERR_TRY
  185.     {
  186.         if (capacity > long(text->text._maximum - kTradMacTextOffset))
  187.         {
  188.             unsigned char *newBuffer = new unsigned char[capacity+kTradMacTextOffset];
  189.             ::FW_PrimitiveCopyMemory(text->text._buffer, newBuffer, text->text._length);
  190.             if (deletePrevBuffer)
  191.                 delete [] text->text._buffer;
  192.             text->text._buffer = newBuffer;
  193.             text->text._maximum = capacity+kTradMacTextOffset;
  194.         }
  195.     }
  196.     FW_ERR_CATCH
  197. }
  198.  
  199. //----------------------------------------------------------------------------------------
  200. // TradMac_SetLength
  201. //----------------------------------------------------------------------------------------
  202.  
  203. static void TradMac_SetLength(ODIText *text, long length,
  204.                                         FW_PlatformError* error)
  205. {
  206.     *error = 0;
  207.     FW_PRIV_ASSERT(length <= long(text->text._maximum - kTradMacTextOffset));
  208.     text->text._length = length + kTradMacTextOffset;
  209. }
  210.  
  211. //----------------------------------------------------------------------------------------
  212. // TradMac_SetLocale
  213. //----------------------------------------------------------------------------------------
  214.  
  215. static void TradMac_SetLocale(ODIText *text, FW_Locale locale, FW_PlatformError* error)
  216. {
  217.     *error = 0;
  218.     ODByteArray *array = &text->text;
  219.     FW_ODTradITextData *iTextData = (FW_ODTradITextData *) array->_buffer;
  220.     iTextData->fLocale = locale;    
  221. }
  222.  
  223. //----------------------------------------------------------------------------------------
  224. // gTraditionalMacFunctions
  225. //----------------------------------------------------------------------------------------
  226.  
  227. FW_ODITextFunctions gTraditionalMacFunctions = 
  228. {
  229.     TradMac_GetODITextParams,
  230.     TradMac_IsCharacterStart,
  231.     TradMac_GetBytePosition,
  232.     TradMac_SetCapacity,
  233.     TradMac_SetLength,
  234.     TradMac_SetLocale
  235. };
  236.  
  237. //========================================================================================
  238. //    Text Format Registry Functions
  239. //========================================================================================
  240.  
  241. struct PrivRegistryEntry
  242. {
  243.     ODITextFormat            fFormat;
  244.     FW_ODITextFunctions*    fFunctions;
  245. };
  246.  
  247. static PrivRegistryEntry gRegistryMap[] =
  248. {
  249.     { kODTraditionalMacText, &gTraditionalMacFunctions }
  250. };
  251.  
  252. const int kNumberFormats = sizeof(gRegistryMap) / sizeof(PrivRegistryEntry);
  253.  
  254. //----------------------------------------------------------------------------------------
  255. // PrivGetFormatFunctions
  256. //----------------------------------------------------------------------------------------
  257.  
  258. static FW_ODITextFunctions* PrivGetFormatFunctions(ODITextFormat format)
  259. {
  260.     // We cache the last format,functions pair used.
  261.     // This not only will speed up the usual case where we're continually
  262.     // just getting the FormatFunctions for the same ODIFormat (i.e. kODTraditionalMacText),
  263.     // it will usually save us from even needing to instantiate the PrivTextFormatMap.
  264.     // Any part that uses kODTraditionalMacText exclusively will never execute 
  265.     // PrivGetTextFormatMap, so it will never instantiate the map.
  266.     
  267.     static ODITextFormat gLastFormat = kODTraditionalMacText;
  268.     static FW_ODITextFunctions* gLastFunctions = &gTraditionalMacFunctions;
  269.     
  270.     FW_ODITextFunctions* result = 0;
  271.     if (format == gLastFormat)
  272.         result = gLastFunctions;
  273.     else
  274.     {
  275.         for (int i=0; i<kNumberFormats; i++)
  276.         {
  277.             if (gRegistryMap[i].fFormat == format)
  278.                 result = gRegistryMap[i].fFunctions;
  279.         }
  280.         if (result)
  281.         {
  282.             gLastFormat = format;
  283.             gLastFunctions = result;
  284.         }
  285.     }
  286.     return result;
  287. }
  288.  
  289. //========================================================================================
  290. //    ODIText Parameter Functions
  291. //========================================================================================
  292.  
  293. //----------------------------------------------------------------------------------------
  294. // FW_TextParams_GetParams
  295. //----------------------------------------------------------------------------------------
  296.  
  297. void FW_TextParams_GetParams(ODIText *text, 
  298.                             FW_ODITextParams* params,
  299.                             FW_PlatformError* error)
  300. {
  301.     FW_ODITextFunctions* functions = PrivGetFormatFunctions(text->format);
  302.     FW_PRIV_ASSERT(functions);
  303.     (functions->fGetParams)(text, params, error);
  304. }
  305.  
  306. //----------------------------------------------------------------------------------------
  307. // FW_TextParams_IsCharacterStart
  308. //----------------------------------------------------------------------------------------
  309.  
  310. FW_Boolean FW_TextParams_IsCharacterStart(ODIText *text,                                             
  311.                                     FW_BytePosition knownCharacterStartPosition, 
  312.                                     FW_BytePosition positionToCheck,
  313.                                     FW_PlatformError* error)
  314. {
  315.     FW_ODITextFunctions* functions = PrivGetFormatFunctions(text->format);
  316.     FW_PRIV_ASSERT(functions);
  317.     return (functions->fIsCharacter)(text, knownCharacterStartPosition, positionToCheck, error);
  318. }
  319.  
  320. //----------------------------------------------------------------------------------------
  321. // FW_TextParams_GetBytePosition
  322. //----------------------------------------------------------------------------------------
  323.  
  324. FW_BytePosition FW_TextParams_GetBytePosition(ODIText *text,
  325.                                     FW_CharacterPosition position,
  326.                                     FW_PlatformError* error)
  327. {
  328.     FW_ODITextFunctions* functions = PrivGetFormatFunctions(text->format);
  329.     FW_PRIV_ASSERT(functions);
  330.     return (functions->fGetBytePos)(text, position, error);
  331. }
  332.  
  333. //----------------------------------------------------------------------------------------
  334. // FW_TextParams_SetCapacity
  335. //----------------------------------------------------------------------------------------
  336.  
  337. void FW_TextParams_SetCapacity(ODIText *text, 
  338.                                 long capacity, 
  339.                                 FW_Boolean deletePrevBuffer,
  340.                                 FW_ODITextParams* params,
  341.                                 FW_PlatformError* error)
  342. {
  343.     FW_ODITextFunctions* functions = PrivGetFormatFunctions(text->format);
  344.     FW_PRIV_ASSERT(functions);
  345.     (functions->fSetCapacity)(text, capacity, deletePrevBuffer, error);
  346.     if (!*error) 
  347.         (functions->fGetParams)(text, params, error);
  348. }
  349.  
  350. //----------------------------------------------------------------------------------------
  351. // FW_TextParams_SetLength
  352. //----------------------------------------------------------------------------------------
  353.  
  354. void FW_TextParams_SetLength(ODIText *text, 
  355.                                 long length, 
  356.                                 FW_ODITextParams* params,
  357.                                 FW_PlatformError* error)
  358. {
  359.     FW_ODITextFunctions* functions = PrivGetFormatFunctions(text->format);
  360.     FW_PRIV_ASSERT(functions);
  361.     (functions->fSetLength)(text, length, error);
  362.     if (!*error) 
  363.         (functions->fGetParams)(text, params, error);
  364. }
  365.  
  366. //----------------------------------------------------------------------------------------
  367. // FW_TextParams_SetLength
  368. //----------------------------------------------------------------------------------------
  369.  
  370. void FW_TextParams_SetLocale(ODIText *text, 
  371.                                 FW_Locale locale,
  372.                                 FW_ODITextParams* params,
  373.                                 FW_PlatformError* error)
  374. {
  375.     FW_ODITextFunctions* functions = PrivGetFormatFunctions(text->format);
  376.     FW_PRIV_ASSERT(functions);
  377.     (functions->fSetLocale)(text, locale, error);
  378.     if (!*error) 
  379.         (functions->fGetParams)(text, params, error);
  380. }
  381.